package pe.seleccion;


import pe.algenetico.MiRandom;
import pe.cromosoma.Cromosoma;

public class SeleccionRanking implements Seleccion{

	private static final double Beta_ = 1.9;
	
	public Cromosoma[] seleccion(int tam_pob, int tam_elite, Cromosoma[] initPop, MiRandom ran, int funcion, int param) {
		Cromosoma[] sortedPop = ordenarPoblacion(initPop);
		Cromosoma[] futureParents = new Cromosoma[sortedPop.length];
		futureParents[0]=sortedPop[0];futureParents[1]=sortedPop[1];
		int numOfParents =2;
		
		double[] fitnessSegments = rankPopulation(tam_pob);
		double entireSegment = fitnessSegments[fitnessSegments.length-1];
		while(numOfParents<futureParents.length){
			double x = (double)(ran.r.nextDouble()*entireSegment);
			if(x<=fitnessSegments[0]) {
				/*** First Individual was Selected **/
				futureParents[numOfParents]=sortedPop[0];
				numOfParents++;
			}
			else
				for(int i=1; i<futureParents.length; i++)
					if(x>fitnessSegments[i-1] && x<=fitnessSegments[i]){
						/*** i'th Idividual was Selected **/
						futureParents[numOfParents]=sortedPop[i];
						numOfParents++;
					}
		} 
		return futureParents;
		}
	
	private double[] rankPopulation(int tam_pob){
		double[] fitnessSegments = new double[tam_pob];
		for(int i=0 ; i<fitnessSegments.length ; i++){
			double probOfIth = (double)i/tam_pob;
			probOfIth = probOfIth*2*(Beta_-1);
			probOfIth = Beta_ - probOfIth;
			probOfIth = (double)probOfIth*((double)1/tam_pob);
			if(i!=0)
				fitnessSegments[i] = fitnessSegments[i-1] + probOfIth;
			else
				fitnessSegments[i] = probOfIth;
		}
		return fitnessSegments;
	}
	
		//Metodo de ordenacion
	private Cromosoma[] ordenarPoblacion(Cromosoma[] pob){
		Cromosoma temp=null;
		for (int i=1; i<pob.length; i++)
			for (int j=0 ; j<pob.length - 1; j++)
			if (pob[j].getAptitud() < pob[j+1].getAptitud()){
				temp = pob[j];
				pob[j] = pob[j+1];
				pob[j+1] = temp;
			}
		return pob;
	}
	
}
